package com.zyk.scaffold.common.basic;

import org.apache.commons.lang3.RandomStringUtils;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class BasicException extends RuntimeException implements BasicErrorCode {
    private static final long serialVersionUID = -5365630128856068163L;
    private int code;
    private String message;
    private String stack;

    public BasicException(BasicErrorCode basicErrorCode) {
        super(basicErrorCode.getMessage());
        this.code = basicErrorCode.getCode();
        this.message = basicErrorCode.getMessage();
    }

    public BasicException(BasicErrorCode basicErrorCode, Throwable cause) {
        super(basicErrorCode.getMessage(), cause);
        this.code = basicErrorCode.getCode();
        this.message = basicErrorCode.getMessage();
        this.stack = parseStackTrace(cause);
    }

    public BasicException(String message, int errorCode) {
        super(message);
        this.code = errorCode;
        this.message = message;
    }

    public BasicException(String message, Throwable cause, int errorCode) {
        super(message);
        this.code = errorCode;
        this.message = message;
        this.stack = parseStackTrace(cause);
    }

    private String parseStackTrace(Throwable error) {
        if (error == null) {
            return null;
        }
        StringWriter stackTrace = new StringWriter();
        error.printStackTrace(new PrintWriter(stackTrace));
        stackTrace.flush();
        return RandomStringUtils.randomAlphanumeric(10) + Base64.getEncoder().encodeToString(stackTrace.toString().getBytes(StandardCharsets.UTF_8));
    }

    @Override
    public int getCode() {
        return code;
    }

    @Override
    public String getMessage() {
        return message;
    }

    @Override
    public String getStack() {
        return stack;
    }
}
